#include "hal.h"
#include "vga_text.h"
#include "idt.h"
#include "mydebug.h"

typedef struct _idtr
{
	uint16_t limit;
	uint32_t base;
}idtr;

static idtr _idtRegister;
static idt_descriptor _idt[I86_MAX_INTERRUPTS];

void i86_idt_install()
{
	__asm lidt [_idtRegister]
}

void i86_install_ir(int intNo,I86_IR_HANDLER irq,uint16_t selector,uint16_t flags)
{
	if(intNo > I86_MAX_INTERRUPTS)
		return;
	
	if(!irq)
		return;

	memset(&_idt[intNo],0,sizeof(idt_descriptor));

	uint64_t base = (uint64_t)&(*irq);

	uint32_t base32 = base;

	_idt[intNo].irOffsetLo = (uint16_t)(base & 0xffff);
	_idt[intNo].irOffsetHi = (uint16_t)((base >> 16) & 0xffff);
	_idt[intNo].segSelector = selector;
	_idt[intNo].flags = (uint8_t)flags;
	_idt[intNo].reserved = 0;
}

void i86_irq_default_handler()
{
	disable();
	vga_text_mode_puts("\ndefault handler\n");
	for(;;);
}

void i86_idt_initialize(uint16_t selector)
{
	_idtRegister.limit = (uint16_t)(sizeof(idt_descriptor) * I86_MAX_INTERRUPTS) - 1;
	_idtRegister.base = (uint32_t)&_idt[0];

	memset(_idt,0,sizeof(idt_descriptor) * I86_MAX_INTERRUPTS - 1);

	for(int i = 0;i < I86_MAX_INTERRUPTS;i++)
	{
		i86_install_ir(i,i86_irq_default_vector[i],selector,I86_IDT_DESC_PRESENT | I86_IDT_DESC_BIT32);
	}

	i86_idt_install();
}